#ifndef __BSTREEEXTENDED_H__
#define __BSTREEEXTENDED_H__

#include "../../bstree/src/bstree.h"
#include "wordcontainer.h"
#include "bstreeregisterclasses.h"
#include "frontcodingmanager.h"
#include "../../bstree/src/bsIterator.h"
#include "../../bstree/src/node.h"
#include "../../bstree/src/leaf_node.h"
#include "../../common/file_pointer.h"
#include "bstreeregisterclasses.h"


namespace invertedindex{

class BSTreeExtended : public bstree::BSTree{
	private:
		unsigned int nodeSize;
	public:
		BSTreeExtended(unsigned int nodeSize,const RegisterFactory& factory,
						const RegisterFactory& factoryNivel,
						const std::string& nodesFilename):
						bstree::BSTree(nodeSize,factory,factoryNivel, nodesFilename){
			this->nodeSize=nodeSize;
		}

	
	
		std::ostream& toOstreamFC(std::ostream& out, unsigned int offset){
			//Cargo primer registro bloque
			unsigned int nodeOffsetW = offset;
			bstree::Node* node=NULL;
			/* A partir de los hijos de la raiz empiezo a levantar nodos */
			if(nodeOffsetW!=OFFSET_ROOT)
				node = manager.readNode(nodeOffsetW);
			else
				node = this->root;
				
			if(node->getLevel()==bstree::Node::LEAF_LEVEL){
				bstree::LeafNode* lnode = dynamic_cast<bstree::LeafNode*>(node);
				out << "/ ** Imprimiendo Nodo Hoja ** /" << std::endl;
				out << "\t --- Informacion de cabecera ---" << std::endl;
				out << "\t Offset del Nodo : " << nodeOffsetW << std::endl;
				out << "\t Cantidad de Registros : " << node->getRegCount() << std::endl;
				out << "\t Nivel : " << node->getLevel() << std::endl;
				out << "\t Siguiente : "<<lnode->getNextNode()<<std::endl;
				out << "\t Anterior : "<<lnode->getPreviousNode()<<std::endl;
				out << "\t -- Informacion de los registros ---" << std::endl;
				
				unsigned int regCount= node->getRegCount();
				bstree::BSIterator bsIter(nodeOffsetW, false, &(this->manager));
				for(unsigned int ss=0;ss<regCount;ss++){
					out<<"\n\tComienzo registro "<<ss<<std::endl;
					KeyVal* kv = dynamic_cast<KeyVal*>(bsIter.getRegister());	
					//(*it)->toOstream(out);
					std::pair<unsigned int, char*> keyWord = kv->getKey();
					WordContainer wcKey(keyWord.first, keyWord.second, kv->getIdKey());
					BlockPointer* bpAux=kv->getBP();
					wcKey.setBP(bpAux);
					delete bpAux;
				
					std::pair<unsigned int, char*> lexico = kv->getLexico();
					FrontCodingManager fcm(wcKey, kv->getWordCount(),lexico.second);
					fcm.toOstream(out);
					delete[] keyWord.second;
					delete[] lexico.second;
					delete kv;
					bsIter.sig();
				}	
				out << "/ ** Fin Nodo Hoja ** /" << std::endl;
				//Paso siguiente registro
				

			}
			else{
				std::queue<unsigned int> offsets;
				node->toOstream(out, offsets);
			}
			if(node!=this->root)delete node;
			return out;
		}

	
};

}

#endif // __BSTREEEXTENDED_H__
